package com.example.nsl.behavior;


import android.animation.TimeInterpolator;
import android.animation.ValueAnimator;
import android.annotation.SuppressLint;
import android.content.Context;
import android.graphics.Rect;
import android.os.Build;
import android.util.AttributeSet;
import android.util.Log;
import android.view.View;
import android.view.animation.DecelerateInterpolator;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.RequiresApi;
import androidx.appcompat.widget.AppCompatImageView;
import androidx.coordinatorlayout.widget.CoordinatorLayout;
import androidx.core.math.MathUtils;
import androidx.core.view.ViewCompat;
import androidx.core.view.WindowInsetsCompat;
import androidx.recyclerview.widget.RecyclerView;

import com.example.nsl.R;
import com.google.android.material.animation.AnimationUtils;

public class RecycleBavior extends ViewOffsetBehavior {

    private View desView;
    public RecycleBavior(){
    }

    public RecycleBavior(@NonNull Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
    }

    private ValueAnimator offsetAnimator;
    @RequiresApi(api = Build.VERSION_CODES.M)
    @Override
    protected void layoutChild(@NonNull CoordinatorLayout parent, @NonNull View child, int layoutDirection) {
        super.layoutChild(parent, child, layoutDirection);

    }



    @Override
    public boolean onStartNestedScroll(@NonNull CoordinatorLayout coordinatorLayout, @NonNull View child,
                                       @NonNull View directTargetChild, @NonNull View target, int axes, int type) {
        Log.e("RecycleBavior"," onStartNestedScroll: " );
        if (offsetAnimator != null && offsetAnimator.isRunning()) {
            offsetAnimator.cancel();
            offsetAnimator=null;
        }
        if(desView==null) {
            desView = coordinatorLayout.findViewById(R.id.desView);
        }
        return axes == ViewCompat.SCROLL_AXIS_HORIZONTAL;
    }


    @Override
    public void onNestedScroll(@NonNull CoordinatorLayout coordinatorLayout, @NonNull View child,
                               @NonNull View target,
                               int dxConsumed, int dyConsumed,
                               int dxUnconsumed, int dyUnconsumed,
                               int type, @NonNull int[] consumed) {
        super.onNestedScroll(coordinatorLayout, child, target, dxConsumed, dyConsumed, dxUnconsumed, dyUnconsumed, type, consumed);
    }

    @Override
    public void onNestedPreScroll(@NonNull CoordinatorLayout coordinatorLayout, @NonNull View child,
                                  @NonNull View target, int dx, int dy,
                                  @NonNull int[] consumed, int type) {
        super.onNestedPreScroll(coordinatorLayout, child, target, dx, dy, consumed, type);

        int maxRight=desView.getMeasuredWidth();
        int maxMaxRight= (int) (desView.getMeasuredWidth()/3f*5);

        RecyclerView childRecycView= (RecyclerView) child;

        Log.e("RecycleBavior"," onNestedPreScroll  dx: " + dx   + " type:"+ type);
        if(dx > 0) {  //手指向左边滑动 <<<<<<<<<<<<<<<<<<<<<<<<<<------
            if (type == ViewCompat.TYPE_NON_TOUCH) { //如果是惯性滑动的话，需要处理滑动到最大尺寸的位置哦
                //并且只考虑当前情况下的惯性滑动，其他情况下不做任何考虑
                if (-maxRight < getLeftAndRightOffset() && !child.canScrollHorizontally(1)) {
                    int willDes=getLeftAndRightOffset() - dx; // 如果可以的话，最大将要滑动的位置在哪里
                    if(willDes < -maxRight){// 但是你要滑动这里是不行的
                        setLeftAndRightOffset(-maxRight);// 你最多只能滑动到这里来了
                        consumed[0] = dx;// 此处要消耗掉全部的消费，
                    }else {
                        setLeftAndRightOffset(getLeftAndRightOffset() - dx);
                        consumed[0] = dx;
                    }
                }
            }else if (type == ViewCompat.TYPE_TOUCH){// 非惯性滑动的话，此处可以滑动更大的距离

                // 如果RecycleView的位置便宜了
                if(getLeftAndRightOffset()> 0){
                    int willDes=getLeftAndRightOffset() - dx; // 如果可以的话，最大将要滑动的位置在哪里
                    if(willDes < 0){// 但是你要滑动这里是不行的
                        setLeftAndRightOffset(0);// 你最多只能滑动到这里来了
                        consumed[0] = -willDes;// 还有多少距离没有消化，返回回去
                    }else {
                        setLeftAndRightOffset(getLeftAndRightOffset() - dx);
                        consumed[0] = dx;
                    }
                    return;
                }


                if (-maxMaxRight < getLeftAndRightOffset() && !child.canScrollHorizontally(1)) {
                    int willDes=getLeftAndRightOffset() - dx; // 如果可以的话，最大将要滑动的位置在哪里
                    if(willDes < -maxMaxRight){// 但是你要滑动这里是不行的
                        setLeftAndRightOffset(-maxMaxRight);// 你最多只能滑动到这里来了
                        consumed[0] = - (maxMaxRight+willDes);// 此处要消耗的距离是多少呢
                    }else {
                        setLeftAndRightOffset(getLeftAndRightOffset() - dx);
                        consumed[0] = dx;
                    }

                }
            }
        }else  if(dx < 0){ //手指向右边边滑动 ------->>>>>>>>>>>>>>>>>>>>>>>>>>>>>
            if (type == ViewCompat.TYPE_NON_TOUCH) {

                // 如果RecycleView的位置便宜了
                if(getLeftAndRightOffset()<0){
                    int willDes=getLeftAndRightOffset() - dx; // 如果可以的话，最大将要滑动的位置在哪里
                    if(willDes > 0){// 但是你要滑动这里是不行的
                        setLeftAndRightOffset(0);// 你最多只能滑动到这里来了
                        consumed[0] = -willDes;// 还有多少距离没有消化，返回回去
                    }else {
                        setLeftAndRightOffset(getLeftAndRightOffset() - dx);
                        consumed[0] = dx;
                    }
                }
                return;
            }

            // 如果RecycleView的位置便宜了
            if(getLeftAndRightOffset()<0){
                int willDes=getLeftAndRightOffset() - dx; // 如果可以的话，最大将要滑动的位置在哪里
                if(willDes > 0){// 但是你要滑动这里是不行的
                    setLeftAndRightOffset(0);// 你最多只能滑动到这里来了
                    consumed[0] = -willDes;// 还有多少距离没有消化，返回回去
                }else {
                    setLeftAndRightOffset(getLeftAndRightOffset() - dx);
                    consumed[0] = dx;
                }
                return;
            }


            if (maxRight > (getLeftAndRightOffset()) && !child.canScrollHorizontally(-1)) {
                int willDes=getLeftAndRightOffset() - dx; // 如果可以的话，最大将要滑动的位置在哪里
                if(willDes> maxRight){// 但是你要滑动这里是不行的
                    setLeftAndRightOffset(maxRight);// 你最多只能滑动到这里来了
                    consumed[0] = maxRight-willDes;// 还有多少距离没有消化，返回回去
                }else {
                    setLeftAndRightOffset(getLeftAndRightOffset() - dx);
                    consumed[0] = dx;
                }
            }
        }
    }

    @Override
    public void onStopNestedScroll(@NonNull CoordinatorLayout coordinatorLayout, @NonNull View child, @NonNull View target, int type) {
        super.onStopNestedScroll(coordinatorLayout, child, target, type);
        int minMaxRight= desView.getMeasuredWidth();
        if(getLeftAndRightOffset()>0) {
            animateOffsetWithDuration(target, 0, 200);
        }else if(getLeftAndRightOffset() <0 && Math.abs(getLeftAndRightOffset())> minMaxRight){
            animateOffsetRight(target, 0, 200);
        }
    }



    public static final TimeInterpolator DECELERATE_INTERPOLATOR = new DecelerateInterpolator();
    private static final int MAX_OFFSET_ANIMATION_DURATION = 117; // ms
    private void animateOffsetWithDuration(
            View target,
            final int offset,
            final int duration) {
            if (offsetAnimator != null && offsetAnimator.isRunning()) {
                offsetAnimator.cancel();
                offsetAnimator=null;
            }

        if (offsetAnimator == null) {
            offsetAnimator = new ValueAnimator();
            offsetAnimator.setInterpolator(DECELERATE_INTERPOLATOR);
            offsetAnimator.addUpdateListener(
                    new ValueAnimator.AnimatorUpdateListener() {
                        @Override
                        public void onAnimationUpdate(@NonNull ValueAnimator animator) {
                            setLeftAndRightOffset((int) animator.getAnimatedValue());
                        }
                    });
        } else {
            offsetAnimator.cancel();
        }
        offsetAnimator.setDuration(Math.min(duration, MAX_OFFSET_ANIMATION_DURATION));
        offsetAnimator.setIntValues(getLeftAndRightOffset(), 0);
        offsetAnimator.start();
    }

    private void animateOffsetRight(
            View target,
            final int offset,
            final int duration) {
        if (offsetAnimator != null && offsetAnimator.isRunning()) {
            offsetAnimator.cancel();
            offsetAnimator=null;
        }

        if (offsetAnimator == null) {
            offsetAnimator = new ValueAnimator();
            offsetAnimator.setInterpolator(DECELERATE_INTERPOLATOR);
            offsetAnimator.addUpdateListener(
                    new ValueAnimator.AnimatorUpdateListener() {
                        @Override
                        public void onAnimationUpdate(@NonNull ValueAnimator animator) {
                            setLeftAndRightOffset((int) animator.getAnimatedValue());
                        }
                    });
        } else {
            offsetAnimator.cancel();
        }
        int minMaxRight= desView.getMeasuredWidth();
        offsetAnimator.setDuration(Math.min(duration, MAX_OFFSET_ANIMATION_DURATION));
        offsetAnimator.setIntValues(getLeftAndRightOffset(), -minMaxRight);
        offsetAnimator.start();
    }


}
